package com.magina.antiPro.controller;


import com.google.common.base.Preconditions;
import com.magina.antiPro.component.AsyncTask;
import com.magina.antiPro.exception.BusinessException;
import com.magina.antiPro.response.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

@Api(value = "/testAsyncTask", description = "测试异步异常接口")
@RequestMapping("/testAsyncTask")
@RestController
@Slf4j
public class AsyncTaskTestController {


    @Autowired
    private AsyncTask asyncTask;

    @ApiOperation(value = "测试异步异常(有返回值)", notes = "测试异步异常(有返回值)")
    @GetMapping("/doTaskExceptionHavingData")
    public Response doTaskExceptionHavingData() throws InterruptedException, ExecutionException, BusinessException {
        log.info("========测试异步异常(有返回值)========");
        long currentTimeMillis = System.currentTimeMillis();
        asyncTask.task1();
        asyncTask.task2();
        log.info("耗时1:" +(System.currentTimeMillis() - currentTimeMillis));
        Future future = asyncTask.task3();
        log.info("耗时2:" +(System.currentTimeMillis() - currentTimeMillis));
//        //如果不调用get() 会使task3的线程直接再底层调用的时候直接挂.无返回.主线程继续跑完 .接口返回2000正常
        future.get();
        log.info("耗时3:" +(System.currentTimeMillis() - currentTimeMillis));
        //如果直接catch 则按照自定义的catch 返回,不catch 则根据GobalExpectionHandler捕获的来处理
//        try{
//            asyncTask.task3().get();
//        }catch (ExecutionException e){
//        log.info("终于捕获了有返回值的异常!!!!");
//            return Response.fail("qwe","exe_error",e.getCause().getMessage());
//        }
        long currentTimeMillis1 = System.currentTimeMillis();
        return Response.succeed("测试异步异常(有返回值)task任务总耗时:" + (currentTimeMillis1 - currentTimeMillis) + "ms");
    }

    @ApiOperation(value = "测试异步异常(无返回值)", notes = "测试异步异常(无返回值)")
    @GetMapping("/doTaskExceptionHavingVoid")
    public Response doTaskExceptionHavingVoid() throws InterruptedException, ExecutionException, BusinessException {
        log.info("========测试异步异常(无返回值)========");
        long currentTimeMillis = System.currentTimeMillis();
        asyncTask.task1();
        asyncTask.task2();
        //暂时无法catch 无返回值的异步方法的异常
        try {
            asyncTask.taskException1();
        } catch (Exception e) {
            if (e instanceof BusinessException) {
                return Response.fail("11111", "magina_test_void", e.getMessage());
            }
            if (e instanceof ExecutionException) {
                return Response.fail("11112", "magina_test_void", e.getMessage());
            }
        }
        long currentTimeMillis1 = System.currentTimeMillis();
        return Response.succeed("测试异步异常(无返回值)task任务总耗时:" + (currentTimeMillis1 - currentTimeMillis) + "ms");
    }

    @ApiOperation(value = "测试异步异常(无返回值)2", notes = "测试异步异常(无返回值)2")
    @GetMapping("/doTaskExceptionHavingVoid2")
    public Response doTaskExceptionHavingVoid2() throws InterruptedException, ExecutionException, BusinessException {
        log.info("========测试异步异常(无返回值)========");
        long currentTimeMillis = System.currentTimeMillis();
        asyncTask.task1();
        asyncTask.task2();
        //暂时无法catch 无返回值的异步方法的异常
//        try {
            asyncTask.taskException2();
//        } catch (Exception e) {
//            if (e instanceof BusinessException) {
//                return Response.fail("11111", "magina_test_void", e.getMessage());
//            }
//            if (e instanceof ExecutionException) {
//                return Response.fail("11112", "magina_test_void", e.getMessage());
//            }
//        }
        long currentTimeMillis1 = System.currentTimeMillis();
        return Response.succeed("测试异步异常(无返回值)task任务总耗时:" + (currentTimeMillis1 - currentTimeMillis) + "ms");
    }

    @ApiOperation(value = "调用异步方法(不测试异常)", notes = "调用异步方法(不测试异常)")
    @GetMapping("/doTaskNoException")
    public Response doTaskNoException() throws InterruptedException, ExecutionException, BusinessException {
        log.info("========调用异步方法(不测试异常)========");
        long currentTimeMillis = System.currentTimeMillis();
        asyncTask.task1();
        asyncTask.task2();
        asyncTask.task3_0();
        long currentTimeMillis1 = System.currentTimeMillis();
        return Response.succeed("调用异步方法(不测试异常)task任务总耗时:" + (currentTimeMillis1 - currentTimeMillis) + "ms");
    }


    @ApiOperation(value = "testLambdaEx", notes = "testLambdaEx",tags ="testLambdaEx")
    @PostMapping("/testLambdaEx")
    public Response testLambdaEx() throws BusinessException {
        log.info("========testLambdaEx========");
        List<Integer> testList = Arrays.asList(1,2,3,4,5,0);
        //for循环可以catch.Preconditions的illageal异常
//        for (Integer p : testList){
//            if(p == 1){
//                System.out.println("asd");
//                Preconditions.checkArgument(p != 1 ,"发现异常了");
//            }
//        };
        testList.stream().forEach(p ->{
            if(p == 1){
                System.out.println("asd");
                Preconditions.checkArgument(p != 1 ,"异常啊");
            }
        });
        return Response.succeed(testList);
    }

    @ApiOperation(value = "testSameDataChange", notes = "testSameDataChange",tags ="testSameDataChange")
    @PostMapping("/testSameDataChange")
    public Response testSameDataChange() throws BusinessException, InterruptedException, ExecutionException {
        log.info("========testSameDataChange========");
        long currentTimeMillis = System.currentTimeMillis();
//        List<Integer> testList = Arrays.asList(1,2,3,4,5,0);
        List<Integer> testList = new ArrayList<Integer>();
        testList.add(11);
        testList.add(12);
//        testList1.add(13);
//        List<Integer> testList2 = Arrays.asList(1,2,3,4,5,0);
//        List<Integer> testList3 = Arrays.asList(1,2,3,4,5,0);
        List<Future> futureList = Lists.newArrayList();
        Future future1 = asyncTask.testSameDataChange1(testList);
        Future future2 = asyncTask.testSameDataChange2(testList);
        Future future3 = asyncTask.testSameDataChange3(testList);
        futureList.add(future1);
        futureList.add(future2);
        futureList.add(future3);
//        ExecutorService exs = Executors.newFixedThreadPool(5);
//        CompletionService<List> completionService = new ExecutorCompletionService<List>(exs);
        for (int i = 0; i < futureList.size(); i++) {
//            completionService.take().get();//采用completionService.take()，内部维护阻塞队列，任务先完成的先获取到
            while (true){
                if(futureList.get(i).isDone() && !futureList.get(i).isCancelled()){
                    //可以在异步方法里面对testlist操作.也可以等返回值addAll()
                   futureList.get(i).get();
//                    System.out.println(innerLi);
//                    testList.addAll(innerLi);
                    break;
                }else {
                    Thread.sleep(500);
                }
            }
        }
//        exs.shutdown();
        return Response.succeed(testList,"testSameDataChange_task任务总耗时:" + (System.currentTimeMillis() - currentTimeMillis) + "ms");
    }
}

